Electron 进程间通信 您所在的位置:网站首页 electron 进程暂用 Electron 进程间通信

Electron 进程间通信

2023-08-12 05:26| 来源: 网络整理| 查看: 265

小知识,大挑战!本文正在参与“  程序员必备小知识  ”创作活动

本文同时参与 「掘力星计划」  ,赢取创作大礼包,挑战创作激励金

Electron 桌面应用有两个进程,分别为主进程和渲染进程。

一、主进程和渲染进程介绍 主进程(Main Process) 应用启动时,会创建个主进程 一个应用有且只有一个主进程 只有主进程可以进行 GUI 的 API 操作,即调用 Native APIs 渲染进程(Renderer Process) Windows 中展示的界面通过渲染进程表现,DOM 操作,node js 一个应用可以有多个渲染进程 要通过主进程才可以访问原生 API(Native APIs),要先跟主进程进行 ipc 通信 二、渲染进程发消息给主进程

其实主要就是两个 API 的使用: 渲染进程里的 ipcRenderer 与 主进程里的 ipcMain

渲染进程发异步消息给主进程 // 渲染进程脚本 const { ipcRenderer } = require('electron') // 发送异步消息 btns[0].addEventListener('click', () => { ipcRenderer.send('msg1', '这是一条来自于异步的消息') }) // 监听消息 ipcRenderer.on('msg1Re', (ev, data) => { console.info(data) }) // 主进程脚本 const { ipcMain } = require('electron') ipcMain.on('msg1', (ev, data) => { console.info(data) // 发送消息给渲染进程 ev.sender.send('msg1Re', '这是一条来自主进程的反馈消息') }) 复制代码 渲染进程发同步消息给主进程 // 渲染进程脚本 const { ipcRenderer } = require('electron') // 发送同步消息 btns[1].addEventListener('click', () => { const result = ipcRenderer.sendSync('msg2', '这是一条来自于同步的消息') console.info(result) }) // 主进程脚本 const { ipcMain } = require('electron') ipcMain.on('msg2', (ev, data) => { console.info(data) // 反馈消息 ev.returnValue = '这是一条来自主进程的同步反馈消息' }) 复制代码 三、主进程发消息给渲染进程 // 主线程脚本 BrowserWindow.getFocusedWindow().webContents.send( 'mtp', '主进程发送消息给渲染进程' ) // 渲染进程脚本 ipcRenderer.on('mtp', (ev, data) => { console.info(data) }) 复制代码 四、渲染进程间通信 基于本地存储的渲染进程间通信

即采用 localStorage 机制

借助主进程,进行不同渲染进程间的通信 // 发起消息的渲染进程 ipcRenderer.send('mti', '这是条来自于 modal 的消息') // 主进程 ipcMain.on('mti', (ev, data) => { // 通过 id 获取到对应的渲染进程,然后消息传递 BrowserWindow.fromId(mainId).webContents.send('mti2', data) }) // 接收消息的渲染进程 ipcRenderer.on('mti2', (ev, data) => { console.info(data) }) 复制代码 使用 sendTo

前提是要知道另一渲染窗口的 webContents 对应的 id 这边采用 global 存储窗口 ID

const modalMain = new BrowserWindow({ width: 200, height: 200, parent: BrowserWindow.fromId(mainId), // 这样关闭父窗口,则子窗口会一并关闭 webPreferences: { nodeIntegration: true, contextIsolation: false } }) global.sharedObject = { modalMainWebContentsId: modalMain.webContents.id } 复制代码

然后在渲染进程里通过 getGlobal 来获取该 ID 值,并通过 sendTo 来发送消息

let sharedObject = getGlobal('sharedObject') let modalMainWebContentsId = sharedObject.modalMainWebContentsId ipcRenderer.sendTo(modalMainWebContentsId, 'do-some-work', 1) 复制代码

这样其他渲染进程就通过监听 do-some-work 来获取消息

ipcRenderer.on('do-some-work', (e, data) => { console.info(data) }) 复制代码 五、remote

GUI 相关的模块 (如 dialog、menu 等) 仅在主进程中可用, 在渲染进程中不可用。为了在渲染进程中使用它们, 必须使用 remote 模块。这样就可以调用 main 进程的方法,而不用显示发送进程间的信息。

不同的 Electron 版本,remote 获取方式不同。 比如在渲染进程里创建个窗口: In electron > 14.0.0:

安装 @electron/remote 定义 webPreferences 属性 webPreferences: { nodeIntegration: true, // 配合 contextIsolation 才会起作用, 使得渲染进程可以使用 node API contextIsolation: false } 复制代码 主进程脚本: require('@electron/remote/main').initialize() mainWindow.loadFile('index.html') const contents = mainWindow.webContents require('@electron/remote/main').enable(contents) 复制代码 子进程脚本 const { BrowserWindow } = require('@electron/remote') 复制代码

In electron == 14.0.0: 参照官文:www.electronjs.org/docs/breaki… 实际上就是不用在主进程里 enable webContents In electron < 14.0.0:

主进程脚本: { webPreferences: { enableRemoteModule: true } } 复制代码 渲染进程脚本 const { BrowserWindow } = require('electron').remote 复制代码 remote 的几个方法及属性 remote.getCurrentWindow() 返回 BrowserWindow 即此网页所属的窗口 remote.getCurrentWebContents() 返回 webContents 即此网页的 web 内容 remote.getGlobal(name) 返回主进程中 name (例如 global[name]) 的全局变量。 remote.process 主进程中的 process 对象。这与 remote.getGlobal('process') 相同, 但已被缓存。


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有